home *** CD-ROM | disk | FTP | other *** search
Wrap
// ____________________________________________________ // | | // | Project: POWER VIEW IDE | // | File: COMPILE.CPP | // | Compiler: WPP386 (10.6) | // | | // | Subject: Compile & Link stuff | // | | // | Author: Emil Dotchevski | // |____________________________________________________| // // E-mail: zajo@geocities.com // URL: http://www.geocities.com/SiliconValley/Bay/3577 #define uses_errno #define uses_fcntl #define uses_io #define uses_malloc #define uses_process #define uses_stdio #define uses_string #define uses_app #define uses_ht #define uses_icons #define uses_input #define uses_stddlg #define uses_system #define uses_table #define uses_time #define uses_txt #include "PVUSES.H" #include "W.H" #include "TLOG.H" #include "TPROJECT.H" #define _DECLARE_COMPILE_H #include "COMPILE.H" #undef _DECLARE_COMPILE_H /* DEFINES */ #define TRAP_FNAME "PVTRAP.TMP" #define ERR_FNAME "PVERR.TMP" #define OPT_FNAME "PVOPT.TMP" /* MAKE STATUS */ static int make_counter = 0; static char *make_title = ""; void start_of_make( char *_make_title ) { if( make_counter++ ) return; make_title = _make_title; log->clear(); log->redraw(); } void make_status( char *current_file, char *target_file, char *status ) { char *prj; char fname1[_MAX_FNAME], ext1[_MAX_EXT]; char fname2[_MAX_FNAME], ext2[_MAX_EXT]; char fname3[_MAX_FNAME], ext3[_MAX_EXT]; prj = ""; if( project != NULL ) prj = project->filename; _splitpath( prj, NULL, NULL, fname1, ext1 ); _splitpath( current_file, NULL, NULL, fname2, ext2 ); _splitpath( target_file, NULL, NULL, fname3, ext3 ); _title( make_title ); _taleft(); _dialog_xy( desktop_xl - 44, 2 ); action( "Project: %s%s\n\nCurrent file: %s%s\nTarget file: %s%s\n\n%s", fname1, ext1, fname2, ext2, fname3, ext3, status ); } void end_of_make( int show_log ) { if( --make_counter ) return; make_title = ""; done_action(); if( log->vcount && show_log ) log->show_first_error(); log->redraw(); idle( 0 ); } /* VALIDITY CHECKS */ static boolean check_system_time( char *filespec, uint date1, uint time1 ) { time_t t; struct tm tmbuf; uint date0, time0; unsigned long t0, t1; if( time_check!=cmCOM_TIMECHECK ) return 1; t = time( NULL ); _localtime( &t, &tmbuf ); time0 = (tmbuf.tm_hour<<11)|(tmbuf.tm_min<<5)|(tmbuf.tm_sec/2); date0 = ((tmbuf.tm_year-80)<<9)|((tmbuf.tm_mon+1)<<5)|(tmbuf.tm_mday); t0 = (date0<<16)|time0; t1 = (date1<<16)|time1; if( t1>t0 ) { char s[256]; strcpy( s, filespec ); min_path( s ); short_path( s, 30 ); _iwarning(); ok( "File %s has future time stamp (system time not valid, eh?)", s ); return 0; } return 1; } boolean target_valid( char *target, char *source ) //returns 1 if target based on source is valid { uint date1, date2, time1, time2; unsigned long t1, t2; if( !get_date_time( target, date1, time1 ) ) return 0; if( file_size( target ) <= 0 ) return 0; if( ( source == NULL ) || !get_date_time( source, date2, time2 ) ) return 1; t1 = (date1<<16)|time1; t2 = (date2<<16)|time2; if( !check_system_time( target, date1, time1 ) || !check_system_time( source, date2, time2 ) ) return 1; return t1>=t2; } boolean need_make( char *filename ) //check validity of an WATCOM OBJ file { FILE *f; char path[_MAX_PATH], dfile[_MAX_PATH]; long ofs; uint file_date, file_time, date, time, size; char type, l; char _class; boolean result, ok; if( file_size( filename ) <= 0 ) return 1; get_date_time( filename, file_date, file_time ); if( !check_system_time( filename, file_date, file_time ) ) return 0; fexpand( strcpy( path, filename ) ); f = fopen( path, "rb" ); if( f == NULL ) return 1; result = 0; ok = 0; while( !feof( f ) && !ferror( f ) ) { type = 0; size = 0; _class = 0; type = 0; fread( &type, 1, 1, f ); fread( &size, 2, 1, f ); if( size == 0 ) break; ofs = ftell( f ); fread( &_class, 1, 1, f ); fread( &_class, 1, 1, f ); if( ( type == 0x88 ) && ( _class == 0xE9 ) ) { ok = 1; fseek( f, 4, SEEK_CUR ); fread( &l, 1, 1, f ); fread( dfile, l, 1, f ); dfile[l] = 0; if( strstr( "\\WATCOM\\H\\", dfile )==NULL && get_date_time( dfile, date, time ) ) { if( !check_system_time( dfile, date, time ) ) return 0; if( ( file_date < date ) || ( ( file_date == date ) && ( file_time < time ) ) ) { result = 1; break; } } } else if( ok ) break; fseek( f, ofs + size, SEEK_SET ); } fclose( f ); return result; } /* SPAWNING */ static int redirect_handle( int base_handle, int to_handle ) //returns a duplicate of the base handle { int saved; saved = dup( base_handle ); dup2( to_handle, base_handle ); _dos_close( to_handle ); return saved; } static void reset_handle( int saved_handle, int base_handle ) { dup2( saved_handle, base_handle ); _dos_close( saved_handle ); } static char pv_mode; static char pv_char_size; void unhook_system( void ) { pv_mode = scr_mode; pv_char_size = scr_char_size; #ifndef NOMOUSE hide_mouse(); #endif restore_dos_screen(); #if !defined( NOICONS ) && !defined( HGR ) restore_graph_chars(); #endif unhook_drivers(); } void hook_system( void ) { hook_drivers(); #if !defined( NOICONS ) && !defined( HGR ) set_graph_chars(); #endif save_dos_screen(); set_video_mode( pv_mode, pv_char_size ); #ifndef HGR set_blink( 0 ); #endif #ifndef NOMOUSE show_mouse(); #endif application->redraw(); } int exec( uint flags, char *program, char *params, char *redirect, void *history_id ) //execute program w/ params, redirect output as described in flags { const static char *prms[] = { NULL, NULL, NULL }; FILE *f; char parameters[_MAX_PATH]; char buffer[_MAX_PATH]; char *p; int handle1, handle2, in_svd, out_svd, n; boolean success, fsuccess, rsuccess; if( ( flags & teSAVE_CUR ) && ( current_editor != NULL ) && ( current_editor->booleans & ebMODIFIED ) ) message( (Titem *) current_editor->editor, cmSAVE ); if( flags & teSAVE_ALL ) broadcast( cmSAVE_ALL ); if( flags & tePROMPT ) { show_cursor(); _help( htD_EXECUTE ); dialog( "Execute" ); _tselected(); _tacenter(); stext( "Program: %s", 43, program ); vspace(); _focused(); if( flags & teLONG_CMD ) memo( "|~File params", params, MAX_FILE_PARAMS, 40, 8 ); else { _history( history_id ); input( "|~Command line", params, 125, 25 ); } boolean result = bkch(); hide_cursor(); if( !result ) return -1; } if( ( flags & teLONG_CMD ) && ( strlen( params ) > 125 ) ) { *parameters = '@'; f = fopen( tmp_fname( parameters + 1, OPT_FNAME ), "wt" ); if( f == NULL ) { _terror(); ok( "Can't create command line parameters file \"%s\".", parameters+1 ); return -1; } fputs( params, f ); fclose( f ); if( ferror( f ) ) { _terror(); ok( "Can't write command line parameters file \"%s\".", parameters+1 ); return -1; } } else if( strlen( params ) <= 125 ) { strcpy( parameters, params ); for( p = parameters; *p != 0; p++ ) if( *p < ' ' ) *p = ' '; } else { _terror(); ok( "Command line for \"%s\" exceed 125 characters and file command line support is not enabled for this tool. If it can handle \"@file\" command line please check Options / Tools / Edit / Options / Enable long command line.", program ); return -1; } if( !(flags&teDONT_SWAP) ) unhook_system(); handle1 = 0; rsuccess = 1; if( flags & teTRAP ) { if( flags & teTRAP_OUTPUT ) rsuccess = !_dos_creat( tmp_fname( buffer, redirect ), _A_NORMAL, &handle1 ); if( flags & teTRAP_ERRORS ) rsuccess = !_dos_creat( tmp_fname( buffer, TRAP_FNAME ), _A_NORMAL, &handle1 ); if( rsuccess ) out_svd = redirect_handle( 1, handle1 ); } success = 1; if( rsuccess ) { _heapmin(); prms[0] = program; prms[1] = parameters; n = spawnvp( P_WAIT, program, prms ); _heapgrow(); success = ( n != -1 ) || ( ( errno != ENOENT ) && ( errno != ENOMEM ) ); fsuccess = 1; if( flags & teTRAP ) reset_handle( out_svd, 1 ); } if( success && rsuccess && ( flags & teTRAP_ERRORS ) ) { _dos_open( tmp_fname( buffer, TRAP_FNAME ), O_RDONLY, &handle1 ); _dos_creat( tmp_fname( buffer, ERR_FNAME ), _A_NORMAL, &handle2 ); in_svd = redirect_handle( 0, handle1 ); out_svd = redirect_handle( 1, handle2 ); strcpy( parameters, startup_path ); strcat( parameters, redirect ); prms[0] = parameters; prms[1] = NULL; fsuccess = ( spawnv( P_WAIT, parameters, prms ) == 0 ); reset_handle( out_svd, 1 ); reset_handle( in_svd, 0 ); } if( !(flags&teDONT_SWAP) ) hook_system(); if( rsuccess && success && fsuccess && ( flags & teTRAP_ERRORS ) ) { log->logout( "Output from %s:", program ); log->load( buffer ); } if( !success ) { _terror(); if( errno == ENOENT ) ok( "Program not found, \"%s\".", program ); else ok( "Not enough memory to execute \"%s\".", program ); } if( !fsuccess ) { _terror(); if( errno == ENOENT ) ok( "Filter not found, \"%s\".", redirect ); else ok( "Not enough memory to execute filter \"%s\".", redirect ); } if( !rsuccess ) { _terror(); ok( "Can't create temporary trap file \"%s\".", buffer ); } remove( tmp_fname( buffer, TRAP_FNAME ) ); remove( tmp_fname( buffer, ERR_FNAME ) ); remove( tmp_fname( buffer, OPT_FNAME ) ); broadcast( cmSTAMP_CHECK ); idle( 0 ); return n; } /* WATCOM COMPILERS/LINKER INTERFACE */ char *get_local_options( char *buffer, char *file ) { Tproject_entry *pe; uint i; if( project != NULL ) { for( i = 0; i < project->vcount; i++ ) { pe = (Tproject_entry *) project->getptr( i ); if( strcmp( file, pe->filename ) == 0 ) { if( !(pe->options&peEXCLUSIVE) ) { buffer = strchr( buffer, 0 ); *buffer++ = ' '; } strcpy( buffer, pe->command_line ); break; } } } return buffer; } void watcom_command_line( char *result, char *file ) { char *s, *d; *result = 0; if( compiler_options.memory_model == mmSMALL ) strcat( result, "-ms " ); if( compiler_options.memory_model == mmMEDIUM ) strcat( result, "-mm " ); if( compiler_options.memory_model == mmCOMPACT ) strcat( result, "-mc " ); if( compiler_options.memory_model == mmLARGE ) strcat( result, "-ml " ); if( compiler_options.memory_model == mmFLAT_HUGE ) strcat( result, compiler_options.code_size==cs16BITS? "-mh " : "-mf " ); if( compiler_options.code_size == cs16BITS ) { if( compiler_options.cpu == cp8086 ) strcat( result, "-0" ); if( compiler_options.cpu == cp80186 ) strcat( result, "-1" ); if( compiler_options.cpu == cp80286 ) strcat( result, "-2" ); } if( compiler_options.cpu == cp80386 ) strcat( result, "-3" ); if( compiler_options.cpu == cp80486 ) strcat( result, "-4" ); if( compiler_options.cpu == cp80586 ) strcat( result, "-5" ); if( compiler_options.code_size == cs32BITS ) { if( compiler_options.calling_conventions == ccSTACK ) strcat( result, "s" ); if( compiler_options.calling_conventions == ccREGISTER ) strcat( result, "r" ); } if( compiler_options.optimizations & opMULTI_THREAD ) strcat( result, " -bm" ); if( compiler_options.optimizations & opDLL ) strcat( result, " -bd" ); if( compiler_options.optimizations & opDEFAULT_WIN ) strcat( result, " -bw" ); strcat( result, " " ); if( compiler_options.build_target ) { strcat( result, "-bt=" ); strcat( result, build_target[compiler_options.build_target].key ); strcat( result, " " ); } if( compiler_options.options & opPRECOMPILE ) { char fname[_MAX_FNAME]; _splitpath( file, NULL, NULL, fname, NULL ); if( *fname ) { strcat( result, "-fh=" ); strcat( result, default_directories.objects ); strcat( result, fname ); strcat( result, ".PCH " ); } } if( compiler_options.options & opSIGNED_CHARS ) strcat( result, "-j " ); if( compiler_options.options & opENUMS_AS_INTS ) strcat( result, "-ei " ); if( compiler_options.options & opUNIQUE ) strcat( result, "-u " ); if( compiler_options.options & opBASE_TYPES ) strcat( result, "-zg " ); if( compiler_options.options & opCALLS2GROW ) strcat( result, "-sg " ); if( compiler_options.options & opNULLVALID ) strcat( result, "-z " ); if( compiler_options.options & opOUTPUTDECL ) strcat( result, "-v " ); if( compiler_options.options & opINTARGS ) strcat( result, "-ri " ); if( compiler_options.options & opLITERALSINCODE ) strcat( result, "-zc " ); if( compiler_options.options & opSEPARATESEG ) strcat( result, "-zm " ); if( compiler_options.options & opSAVESEGS ) strcat( result, "-r " ); if( compiler_options.options & opSYNTAXONLY ) strcat( result, "-zs " ); if( compiler_options.options & opTOUCHSTACK ) strcat( result, "-st " ); if( compiler_options.far_data_threshold!=32767 ) sprintf( strchr( result, 0 ), "-zt%lu ", compiler_options.far_data_threshold ); if( compiler_options.debug_options & doWARN_IS_ERR ) strcat( result, "-we " ); if( !(compiler_options.options & opDEBUG_INFO) || !(compiler_options.debug_options & doSTACK) ) strcat( result, "-s " ); if( compiler_options.options & opDEBUG_INFO ) { if( compiler_options.stack_frames == sfALWAYS ) strcat( result, "-of+ " ); if( compiler_options.debug_options & doOPTIMIZATIONS ) strcat( result, "-od " ); if( compiler_options.debug_options & doBROWSING ) strcat( result, "-db " ); if( compiler_options.debug_level == dlLINENUMS ) strcat( result, "-d1 " ); if( compiler_options.debug_level == dlFULL ) strcat( result, "-d2 " ); if( compiler_options.debug_level == dlUNREFERENCED ) strcat( result, "-d3 " ); if( compiler_options.debug_format == dfDWARF ) strcat( result, "-hd " ); if( compiler_options.debug_format == dfCODEVIEW ) strcat( result, "-hc " ); } if( ( compiler_options.options & opOPTIMIZATIONS ) && ( ( ( compiler_options.options & opDEBUG_INFO ) == 0 ) || ( ( compiler_options.debug_options & doOPTIMIZATIONS ) == 0 ) ) ) { strcat( result, "-o" ); if( compiler_options.optimize_for == ofSPEED ) strcat( result, "t" ); if( compiler_options.optimize_for == ofSIZE ) strcat( result, "s" ); if( compiler_options.optimizations & opLOOP ) strcat( result, "l" ); if( compiler_options.optimizations & opLOOPUNROLL ) strcat( result, "l+"); if( compiler_options.optimizations & opREORDER ) strcat( result, "r" ); if( compiler_options.optimizations & opCALLRET ==0 ) strcat( result, "c" ); if( compiler_options.optimizations & opRELAX ) strcat( result, "a" ); if( compiler_options.optimizations & opNUMERICALLY ) strcat( result, "n" ); if( compiler_options.optimizations & opLOWMEM ) strcat( result, "o" ); if( compiler_options.optimizations & opINLINE ) strcat( result, "m" ); if( compiler_options.optimizations & opCONSISTENT ) strcat( result, "p" ); if( compiler_options.optimizations & opINTRINSIC ) strcat( result, "i" ); if( compiler_options.optimizations & opUSER ) sprintf( strchr( result, 0 ), "e=%d ", compiler_options.inline_threshold ); strcat( result, " " ); if( compiler_options.optimizations & opPENTIUM ) strcat( result, "-fp5 " ); } strcat( result, "-zp" ); if( compiler_options.alignment == alBYTE ) strcat( result, "1 " ); if( compiler_options.alignment == alWORD ) strcat( result, "2 " ); if( compiler_options.alignment == alDWORD ) strcat( result, "4 " ); if( compiler_options.alignment == alQWORD ) strcat( result, "8 " ); if( compiler_options.ds_segment == dsFLOATS ) strcat( result, "-zdf " ); if( compiler_options.ds_segment == dsLOAD ) strcat( result, "-zdl " ); if( compiler_options.ds_segment == dsPEGGED ) strcat( result, "-zdp " ); if( compiler_options.fsgsss_segments & fsPEGGED ) strcat( result, "-zfp " ); if( compiler_options.fsgsss_segments & gsPEGGED ) strcat( result, "-zgp " ); if( compiler_options.fsgsss_segments & ssNEQDGROUP ) strcat( result, "-zu " ); if( compiler_options.fp_instructions == fpCALLS ) strcat( result, "-fpc " ); if( compiler_options.fp_instructions == fpEMULATION ) strcat( result, "-fpi " ); if( compiler_options.fp_instructions == fpINLINE ) strcat( result, "-fpi87 " ); if( compiler_options.fp_portability == fp8087 ) strcat( result, "-fpr " ); if( compiler_options.fp_portability == fp80287 ) strcat( result, "-fp2 " ); if( compiler_options.fp_portability == fp80387 ) strcat( result, "-fp3 " ); if( compiler_options.exception_handling ) { if( compiler_options.destructions == xhDIRECTCALL ) strcat( result, "-xst " ); if( compiler_options.destructions == xhTABLEDRIVEN ) strcat( result, "-xss " ); } else if( compiler_options.destructions == xhTABLEDRIVEN ) strcat( result, "-xds " ); if( compiler_options.preprocess_options & pfENABLE ) { boolean fl = 1; if( compiler_options.preprocess_options & pfENCRYPT ) fl=0, strcat( result, "-pe " ); if( compiler_options.preprocess_options & pfLINE ) fl=0, strcat( result, "-pl " ); if( compiler_options.preprocess_options & pfPRESERVE ) fl=0, strcat( result, "-pc " ); if( compiler_options.preprocess_options & pfWRAP ) fl=0, sprintf( strchr( result, 0 ), "-pw=%d ", compiler_options.preprocess_wrap ); if( fl ) strcat( result, "-p " ); } if( compiler_options.portability == poANSI ) strcat( result, "-za " ); //if( compiler_options.portability == poWATCOM ) strcat( result, "-ze " ); sprintf( strchr(result,0), "-w%d ", compiler_options.warn_level ); sprintf( strchr(result,0), "-e%d ", compiler_options.max_errors ); if( *compiler_options.code_group_name != '*' ) strcat( result, "-g= " ); if( *compiler_options.code_class_name != '*' ) strcat( result, "-nc= " ); if( *compiler_options.data_segment_name != '*' ) strcat( result, "-gd= " ); if( *compiler_options.module_name != '*' ) strcat( result, "-gm= " ); if( *compiler_options.text_segment_name != '*' ) strcat( result, "-gt= " ); if( *default_directories.objects ) { strcat( result, "-fo=" ); strcat( result, default_directories.objects ); } if( *default_directories.include ) { strcat( result, " -i=" ); strcat( result, default_directories.include ); } strcat( result, " " ); for( d = s = compiler_options.defines; *s; s++ ) { if( *s == ' ' ) { *s = 0; sprintf( strchr( result, 0 ), "-d%s ", d ); *s = ' '; d = s + 1; } } if( d < s ) sprintf( strchr( result, 0 ), "-d%s ", d ); strcat( result, " " ); strcat( result, compiler_options.other ); strcat( result, " " ); strcat( result, file ); get_local_options( result, file ); } void watcom_link_command_line( char *result ) { sprintf( result,"%s\r\n%s%s%s\r\noption stack=%lu%s%s", (compiler_options.options&opDEBUG_INFO)? "\r\ndebug all" : "", linker_options.other_options, linker_options.target_os? "\r\nsystem " : "", target_os[linker_options.target_os].key, linker_options.stack_size, *default_directories.library? "\r\nlibpath " : "", default_directories.library ); } int exec_watcom( char *file ) { char file_to_execute[_MAX_PATH]; char target[_MAX_PATH]; char ext[_MAX_EXT]; char *buffer, *filter; int result; buffer = (char *) MALLOC( MAX_FILE_PARAMS ); watcom_command_line( buffer, file ); _splitpath( file, NULL, NULL, NULL, ext ); strcpy( file_to_execute, "WCC" ); filter = "WCC2LOG"; if( stricmp( ext, ".CPP" ) == 0 ) { strcpy( file_to_execute, "WPP" ); filter = "WPP2LOG"; } if( compiler_options.code_size == cs32BITS ) strcat( file_to_execute, "386" ); make_status( file, obj_file( target, file ), "Executing Watcom C/C++ Compiler..." ); result = exec( teCOMPILER | teTRAP_ERRORS | teDONT_SWAP | teSAVE_ALL | teLONG_CMD, file_to_execute, buffer, filter ); FREE( buffer ); return result; } int exec_linker( char *file ) { uint i; Tproject_entry *pe; char *buffer; char exe[_MAX_PATH]; int result; if( file != NULL ) exe_fname( exe, file ); else exe_fname( exe, project->filename ); buffer = (char *) MALLOC( MAX_FILE_PARAMS ); watcom_link_command_line( buffer ); strcat( buffer, " name " ); strcat( buffer, exe ); strcat( buffer, " file " ); if( file != NULL ) strcat( buffer, file ); else { for( i = 0; i < project->vcount; i++ ) { pe = (Tproject_entry *) project->getptr( i ); if( pe->options & peDONT_LINK ) continue; obj_file( strchr( buffer, 0 ), pe->filename ); strcat( buffer, ", " ); } } make_status( "", exe, "Executing Watcom Linker..." ); result = exec( teCOMPILER|teTRAP_ERRORS|teDONT_SWAP|teLONG_CMD, "WLINK", buffer, "WLNK2LOG" ); FREE( buffer ); if( project!=NULL && memcmp(&project->prj_linker_options,&linker_options,sizeof(Tlinker_options))!=0 ) { project->prj_linker_options = linker_options; project->save_project(); } return result; } boolean compile( void ) //compile current file if not compiled { char *fn; char path[_MAX_PATH]; if( current_editor == NULL ) return 1; if( current_editor->booleans & ebMODIFIED ) message( (Titem *) current_editor->editor, cmSAVE ); fn = ((Tfile_editor *) current_editor->editor)->text_editor->file_name; obj_file( path, fn ); if( need_make( path ) ) exec_watcom( fn ); return !need_make( path ); } boolean link( void ) //link current file/project if not linked { char *fn; char p1[_MAX_PATH], p2[_MAX_PATH]; boolean result; if( project != NULL ) result = project->link( 0 ); else if( current_editor != NULL ) { fn = ((Tfile_editor *) current_editor->editor)->text_editor->file_name; exe_file( p1, fn ); obj_file( p2, fn ); result = 1; if( !target_valid( p1, p2 ) ) result = ( exec_linker( p2 ) == 0 ); } return result; }